package v1

import (
	"fmt"
	"gohub/app/models"
	"gohub/app/models/role"
	"gohub/app/models/user"
	"gohub/app/requests"
	"gohub/app/services"
	"gohub/pkg/config"
	"gohub/pkg/database"
	"gohub/pkg/file"
	"gohub/pkg/helpers"
	"gohub/pkg/response"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type UserManageController struct {
	BaseAPIController
}

func (ctrl *UserManageController) Index(c *gin.Context) {
	request := requests.UserManageRequest{}
	if ok := requests.Validate(c, &request, requests.UserManageSearch); !ok {
		return
	}

	list, pager := user.Paginate(c, request.Size)

	// 基于User结构体扩展
	type userListItem struct {
		user.User `json:",inline"` // 内嵌User字段
		ID2       uint64           `json:"_id"`
		Role      []role.Role      `json:"role"` // 扩展角色信息
		//OpenTime  string           `json:"openTime"` // 覆盖原字段
	}

	formatList := make([]interface{}, len(list))
	for i, item := range list {
		fmt.Printf("=== item: %v\n", item.RoleId)
		formatList[i] = userListItem{
			User: item,
			ID2:  item.ID,
			Role: role.GetRoles(item.RoleId),
			//OpenTime: strconv.FormatInt(user.OpenTime, 10),
		}
	}

	data := map[string]interface{}{
		"list":  formatList,
		"page":  pager.CurrentPage,
		"size":  pager.PerPage,
		"total": pager.TotalCount,
	}
	response.Data(c, data)
}

func (ctrl *UserManageController) GetUserDetail(c *gin.Context) {
	uid := c.Param("id")
	data, _ := services.GetUserDetail(c, uid)
	response.Data(c, data)
}

func (ctrl *UserManageController) DeleteUser(c *gin.Context) {
	userModel := user.Get(c.Param("id"))
	if userModel.ID == 0 {
		response.Abort404(c)
		return
	}

	rowsAffected := userModel.Delete()
	if rowsAffected > 0 {
		response.Success(c)
		return
	}

	response.Abort500(c, "删除失败，请稍后尝试~")
}

// 获取用户拥有的角色
func (ctrl *UserManageController) GetUserRole(c *gin.Context) {
	uid := c.Param("id")
	user := user.Get(uid)
	response.Data(c, map[string]interface{}{
		"role": role.GetRoles(user.RoleId),
		"_id":  uid,
	})
}

type updateUser struct {
	user.User `json:",inline"` // 内嵌User字段
	Roles     []role.Role      `json:"roles"`
}

// 更新用户
func (ctrl *UserManageController) UpdateUser(c *gin.Context) {
	var userItem updateUser
	if err := c.BindJSON(&userItem); err != nil {
		response.BadRequest(c, err)
		return
	}

	var roleids []string
	for _, item := range userItem.Roles {
		roleids = append(roleids, strconv.Itoa(int(item.ID)))
	}

	uid := c.Param("id")
	userModel := user.Get(uid)
	userModel.RoleId = strings.Join(roleids, ",")
	rowsAffected := userModel.Save()
	if rowsAffected > 0 {
		response.Success(c)
	} else {
		response.Abort500(c, "更新失败，请稍后尝试~")
	}
}

type setRoles struct {
	Roles []role.Role `json:"roles"`
}

// 分配用户拥有的角色
func (ctrl *UserManageController) UpdateUserRole(c *gin.Context) {
	var roles setRoles
	if err := c.BindJSON(&roles); err != nil {
		response.BadRequest(c, err)
		return
	}

	var roleids []string
	for _, item := range roles.Roles {
		roleids = append(roleids, strconv.Itoa(int(item.ID)))
	}

	uid := c.Param("id")
	user := user.Get(uid)
	user.RoleId = strings.Join(roleids, ",")
	rowsAffected := user.Save()
	if rowsAffected > 0 {
		response.Success(c)
	} else {
		response.Abort500(c, "更新失败，请稍后尝试~")
	}
}

func (ctrl *UserManageController) Upload(c *gin.Context) {
	request := requests.UserUpdateAvatarRequest{}
	if ok := requests.Validate(c, &request, requests.UserUpdateAvatar); !ok {
		return
	}

	avatar, err := file.SaveUploadAvatar(c, request.Avatar)
	if err != nil {
		response.Abort500(c, "上传头像失败，请稍后尝试~")
		return
	}

	response.Data(c, gin.H{
		"avatar": config.GetString("app.url") + avatar,
	})
}

// 新建用户
func (ctrl *UserManageController) CreateUser(c *gin.Context) {

	// 1. 验证表单
	request := requests.CreateUserRequest{}
	if ok := requests.Validate(c, &request, requests.CreateUser); !ok {
		return
	}

	var roleids []string
	for _, item := range request.Roles {
		roleids = append(roleids, strconv.Itoa(int(item.ID)))
	}

	// 2. 验证成功，创建数据
	userModel := user.User{
		Username: request.Username,
		Mobile:   request.Mobile,
		RoleId:   strings.Join(roleids, ","),
		Avatar:   request.Avatar,
		Password: helpers.MD5(request.Password + config.GetString("app.app_base_salt")),
	}
	userModel.Create()

	if userModel.ID > 0 {
		response.Success(c)
	} else {
		response.Abort500(c, "创建用户失败，请稍后尝试~")
	}
}

func (ctrl *UserManageController) ExportUser(c *gin.Context) {
	list := user.All()
	type userListItem struct {
		user.User `json:",inline"` // 内嵌User字段
		ID2       uint64           `json:"_id"`
		Role      []role.Role      `json:"role"`     // 扩展角色信息
		OpenTime  string           `json:"openTime"` // 覆盖原字段
	}

	formatList := make([]interface{}, len(list))
	for i, item := range list {
		formatList[i] = userListItem{
			User:     item,
			ID2:      item.ID,
			Role:     role.GetRoles(item.RoleId),
			OpenTime: item.GetCreatedAtString(),
		}
	}

	data := map[string]interface{}{
		"list": formatList,
	}
	response.Data(c, data)
}

func (ctrl *UserManageController) ImportUser(c *gin.Context) {
	// 1. 验证请求数据
	request, roleMap, ok := requests.ValidateImportUser(c)
	if !ok {
		response.ValidationError(c, "数据验证失败")
		return
	}

	// 2. 开启事务处理导入
	err := database.DB.Transaction(func(db *gorm.DB) error {
		for _, row := range *request {
			// 解析开通时间
			openTime, _ := time.Parse("2006-01-02", row.OpenTime)

			// 创建用户模型
			userModel := user.User{
				Username: row.Username,
				Mobile:   strconv.Itoa(int(row.Mobile)),
				RoleId:   roleMap[row.Role],
				Password: helpers.MD5(config.GetString("app.default_user_pwd") + config.GetString("app.app_base_salt")),
				CommonTimestampsField: models.CommonTimestampsField{
					CreatedAt: (*models.LocalTime)(&openTime),
				},
			}

			// 保存到数据库
			if err := db.Create(&userModel).Error; err != nil {
				return err
			}
		}
		return nil
	})

	if err != nil {
		response.Abort500(c, "导入用户失败: "+err.Error())
		return
	}

	response.Data(c, gin.H{
		"message": "用户导入成功",
		"count":   len(*request),
	})
}
